package com.aizhixin.lab.course.template.service;

import com.aizhixin.lab.course.template.domain.UploadResultDomain;
import com.aizhixin.lab.course.template.dto.ImportAssistDTO;
import com.aizhixin.lab.course.template.dto.ImportChapterDTO;
import com.aizhixin.lab.course.template.dto.ImportChapterFileDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
import org.apache.commons.compress.archivers.zip.ZipFile;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
public class TemplateImportZipService {
    private static final String TYPE_CHAPTER = "02课程内容";
    private static final String TYPE_ASSIST = "03辅助资料";

    @Autowired
    private UploadService uploadService;

    public Map<String, List> getImportData(File file) {
        Map<String, List> result = new HashMap<>();
        List<ImportChapterDTO> chapterDTOS = new ArrayList<>();
        List<ImportAssistDTO> assistDTOS = new ArrayList<>();
        ZipFile zipFile = null;
        try {
            try {
                zipFile = new ZipFile(file, "GBK");
            } catch (Exception e) {
                zipFile = new ZipFile(file);
            }
            Enumeration<ZipArchiveEntry> enumeration = zipFile.getEntries();
            while (enumeration.hasMoreElements()) {
                ZipArchiveEntry zipArchiveEntry = enumeration.nextElement();
                String fullName = zipArchiveEntry.getName();
                if (fullName.startsWith("__MACOSX") || fullName.endsWith(".DS_Store") || fullName.indexOf("/~") > 0) {
                    continue;
                }
                if (fullName.lastIndexOf("/") == fullName.length() - 1) {
                    fullName = fullName.substring(0, zipArchiveEntry.getName().length() - 1);
                }
                String[] names = fullName.split("/");
                log.info(fullName);
                if (zipArchiveEntry.getName().indexOf(TYPE_CHAPTER + "/") > -1) {
                    int start = 0;
                    for (int i = 0; i < names.length; i++) {
                        String name = names[i];
                        if (name.equals(TYPE_CHAPTER)) {
                            start = i;
                            break;
                        }
                    }
                    int level = names.length - start - 1;
                    if (level == 1) {//章 && zipArchiveEntry.isDirectory()
                        setChapter1DTO(names, chapterDTOS);
                    } else if (level == 2) {//节  不处理章下的文件类型  && zipArchiveEntry.isDirectory()
                        setChapter2DTO(names, chapterDTOS);
                    } else if (level == 3 && !zipArchiveEntry.isDirectory() && names[names.length - 1].indexOf(".") > 0) {//章下的文件
                        InputStream is = zipFile.getInputStream(zipArchiveEntry);
                        setChapter3DTO(names, chapterDTOS, is);
                    } else if (level == 4 && !zipArchiveEntry.isDirectory() && names[names.length - 1].indexOf(".") > 0) {//节下的文件
                        InputStream is = zipFile.getInputStream(zipArchiveEntry);
                        setChapter4DTO(names, chapterDTOS, is);
                    }
                } else if (zipArchiveEntry.getName().indexOf(TYPE_ASSIST + "/") > -1) {
                    int start = 0;
                    for (int i = 0; i < names.length; i++) {
                        String name = names[i];
                        if (name.equals(TYPE_ASSIST)) {
                            start = i;
                            break;
                        }
                    }
                    if (names.length > (start + 1)) {
                        start++;
                        if (zipArchiveEntry.isDirectory()) {
                            setAssistDirDTO(names, start, assistDTOS);
                        } else {
                            InputStream is = zipFile.getInputStream(zipArchiveEntry);
                            setAssistFileDTO(names, start, assistDTOS, is);
                        }
                    }
                }
            }
            if (!chapterDTOS.isEmpty()) {
                result.put("chapterDTOS", chapterDTOS);
            }
            if (!assistDTOS.isEmpty()) {
                result.put("assistDTOS", assistDTOS);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        } finally {
            if (zipFile != null) {
                try {
                    zipFile.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    private void setChapter1DTO(String[] names, List<ImportChapterDTO> chapterList) {
        boolean flag = false;
        String name = splitNotNumber(names[names.length - 1]);
        String no = getNumbers(names[names.length - 1]);
//        for (ImportChapterDTO item : chapterList) {
//            if (item.getName().equals(name) && item.getChapterNo().equals(Integer.parseInt(no) + "")) {
//                flag = true;
//                break;
//            }
//        }
        if (!flag) {
            ImportChapterDTO d = new ImportChapterDTO();
            d.setName(name);
            d.setType(10);
            d.setChapterNo(Integer.parseInt(no) + "");
            chapterList.add(d);
        }
    }

    private void setChapter2DTO(String[] names, List<ImportChapterDTO> chapterList) {
        boolean flag = false;
        String name1 = splitNotNumber(names[names.length - 2]);
        String name2 = names[names.length - 1];
        String no = getNumbers(names[names.length - 1]);
        if (isFileType(name2)) {
            return;
        }
        name2 = splitNotNumber(name2);
        for (ImportChapterDTO item : chapterList) {
            if (item.getName().equals(name1)) {
                if (item.getChapterDTOS() == null) {
                    item.setChapterDTOS(new ArrayList<ImportChapterDTO>());
                }
//                for (ImportChapterDTO subItem : item.getChapterDTOS()) {
//                    if (subItem.getName().equals(name2) && subItem.getChapterNo().equals(item.getChapterNo() + "." + Integer.parseInt(no) + "")) {
//                        flag = true;
//                        break;
//                    }
//                }
                if (!flag) {
                    ImportChapterDTO d = new ImportChapterDTO();
                    d.setName(name2);
                    d.setType(20);
                    d.setChapterNo(item.getChapterNo() + "." + Integer.parseInt(no) + "");
                    item.getChapterDTOS().add(d);
                }
                break;
            }
        }
    }

    private void setChapter3DTO(String[] names, List<ImportChapterDTO> chapterList, InputStream inputStream) {
        boolean flag = false;
        String chapterName = splitNotNumber(names[names.length - 3]);
        String fileType = names[names.length - 2];
        String filename = names[names.length - 1];
        if (isFileType(filename)) {
            return;
        }
        for (ImportChapterDTO chapterDTO : chapterList) {
            if (chapterDTO.getName().equals(chapterName)) {
                if (chapterDTO.getFileDTOS() == null) {
                    chapterDTO.setFileDTOS(new ArrayList<ImportChapterFileDTO>());
                }
                Integer no = 0;
                for (ImportChapterFileDTO file : chapterDTO.getFileDTOS()) {
                    if (file.getNo() < no) {
                        no = file.getNo();
                    }
//                    if (file.getName().equals(filename)) {
//                        flag = true;
//                        break;
//                    }
                }
                if (!flag) {
                    ImportChapterFileDTO d = new ImportChapterFileDTO();
                    d.setName(filename);
                    d.setType(getFileType(fileType));
                    no = no - 1;
                    d.setNo(no);
                    UploadResultDomain result = uploadService.uploadFile(filename, inputStream);
                    if (result != null) {
                        d.setFileKey(result.getKey());
                        d.setFileUrl(result.getFilePath());
                    }
                    chapterDTO.getFileDTOS().add(d);
                }
                break;
            }
        }
    }

    private void setChapter4DTO(String[] names, List<ImportChapterDTO> chapterList, InputStream inputStream) {
        boolean flag = false;
        String chapterName = splitNotNumber(names[names.length - 4]);
        String chapter2Name = splitNotNumber(names[names.length - 3]);
        String fileType = names[names.length - 2];
        String filename = names[names.length - 1];
        for (ImportChapterDTO chapterDTO : chapterList) {
            if (chapterDTO.getName().equals(chapterName)) {
                for (ImportChapterDTO subDTO : chapterDTO.getChapterDTOS()) {
                    if (subDTO.getName().equals(chapter2Name)) {
                        if (subDTO.getFileDTOS() == null) {
                            subDTO.setFileDTOS(new ArrayList<ImportChapterFileDTO>());
                        }
                        Integer no = 0;
                        for (ImportChapterFileDTO file : subDTO.getFileDTOS()) {
                            if (file.getNo() < no) {
                                no = file.getNo();
                            }
//                            if (file.getName().equals(filename)) {
//                                flag = true;
//                                break;
//                            }
                        }
                        if (!flag) {
                            ImportChapterFileDTO d = new ImportChapterFileDTO();
                            d.setName(filename);
                            d.setType(getFileType(fileType));
                            no = no - 1;
                            d.setNo(no);
                            UploadResultDomain result = uploadService.uploadFile(filename, inputStream);
                            if (result != null) {
                                d.setFileKey(result.getKey());
                                d.setFileUrl(result.getFilePath());
                            }
                            subDTO.getFileDTOS().add(d);
                        }
                        break;
                    }
                }
                break;
            }
        }
    }

    private void setAssistDirDTO(String[] names, int start, List<ImportAssistDTO> assistDTOS) {
        String startName = names[start];
        boolean flag = false;
        for (ImportAssistDTO item : assistDTOS) {
            if (item.getName().equals(startName)) {
                flag = true;
                if (names.length > start) {
                    if (item.getChildren() == null) {
                        item.setChildren(new ArrayList<>());
                    }
                    setAssistDirDTO(names, start + 1, item.getChildren());
                }
                break;
            }
        }
        if (!flag) {
            ImportAssistDTO dto = new ImportAssistDTO();
            dto.setName(startName);
            dto.setIsDir(true);
            assistDTOS.add(dto);
        }
    }

    private void setAssistFileDTO(String[] names, int start, List<ImportAssistDTO> assistDTOS, InputStream inputStream) {
        String startName = names[start];
        boolean flag = false;
        for (ImportAssistDTO item : assistDTOS) {
            if (item.getName().equals(startName)) {
                flag = true;
                if (names.length > start) {
                    if (item.getChildren() == null) {
                        item.setChildren(new ArrayList<>());
                    }
                    setAssistFileDTO(names, start + 1, item.getChildren(), inputStream);
                }
                break;
            }
        }
        if (!flag && start == names.length - 1) {
            ImportAssistDTO dto = new ImportAssistDTO();
            dto.setName(startName);
            dto.setIsDir(false);
            UploadResultDomain result = uploadService.uploadFile(startName, inputStream);
            if (result != null) {
                dto.setFileKey(result.getKey());
                dto.setFileUrl(result.getFilePath());
            }
            assistDTOS.add(dto);
        }
    }

    private boolean isFileType(String name) {
        if ("01ppt".equals(name.toLowerCase()) || "02视频".equals(name) || "03任务手册".equals(name) || "04任务参考手册".equals(name) || "05其它".equals(name)) {
            return true;
        } else {
            return false;
        }
    }

    private Integer getFileType(String name) {
        if ("01ppt".equals(name.toLowerCase())) {
            return 10;
        } else if ("02视频".equals(name)) {
            return 20;
        } else if ("03任务手册".equals(name)) {
            return 30;
        } else if ("04任务参考手册".equals(name)) {
            return 40;
        } else if ("05其它".equals(name)) {
            return 50;
        } else if ("课堂笔记".equals(name)) {
            return 60;//暂无用
        } else if ("课堂视频".equals(name)) {
            return 70;//暂无用
        }
        return 0;
    }

    private String getNumbers(String content) {
        Pattern pattern = Pattern.compile("\\d+");
        Matcher matcher = pattern.matcher(content);
        while (matcher.find()) {
            return matcher.group(0);
        }
        return "";
    }

    private String splitNotNumber(String content) {
        String num = getNumbers(content);
        return content.substring(num.length());
    }
}
